﻿using System;
using System.Collections.Generic;
using System.Linq;
using AIStudio.Wpf.DiagramDesigner;

namespace AIStudio.Wpf.Mind.ViewModels
{
    public class MindDiagramViewModel : DiagramViewModel, IMindDiagramViewModel
    {
        #region
        private MindType _mindType = Mind.MindType.Mind;
        public MindType MindType
        {
            get
            {
                return _mindType;
            }
            set
            {
                if (SetProperty(ref _mindType, value))
                {
                    ExecutedChangeMindTypeCommand(value);
                }
            }
        }

        public MindNode RootItem
        {
            get
            {
                return Items.OfType<MindNode>().FirstOrDefault();
            }
        }
        #endregion

        #region 命令
        public SimpleCommand AddRootCommand
        {
            get; private set;
        }

        public SimpleCommand AddParentCommand
        {
            get; private set;
        }

        public SimpleCommand AddChildCommand
        {
            get; private set;
        }

        public SimpleCommand AddPeerCommand
        {
            get; private set;
        }

        public SimpleCommand DeleteSelfCommand
        {
            get; private set;
        }

        public SimpleCommand MoveForwardCommand
        {
            get; private set;
        }

        public SimpleCommand MoveBackCommand
        {
            get; private set;
        }

        private SimpleCommand _changeMindTypeCommand;
        public SimpleCommand ChangeMindTypeCommand
        {
            get
            {
                return this._changeMindTypeCommand ?? (this._changeMindTypeCommand = new SimpleCommand(MindExecuteEnable, this.ExecutedChangeMindTypeCommand));
            }
        }

        public SimpleCommand ChangeMindThemeCommand
        {
            get; private set;
        }

        public SimpleCommand ResetLayout
        {
            get; private set;
        }

        public SimpleCommand Expand2Level1
        {
            get; private set;
        }

        public SimpleCommand Expand2Level2
        {
            get; private set;
        }

        public SimpleCommand Expand2Level3
        {
            get; private set;
        }

        public SimpleCommand Expand2Level4
        {
            get; private set;
        }

        public SimpleCommand Expand2Level5
        {
            get; private set;
        }

        public SimpleCommand Expand2Level6
        {
            get; private set;
        }
        #endregion

        public MindDiagramViewModel()
        {
            AddChildCommand = new SimpleCommand(MindExecuteEnable, ExecuteAddChildCommand);
            AddParentCommand = new SimpleCommand(MindLevelEnable, ExecuteAddParentCommand);
            AddPeerCommand = new SimpleCommand(MindLevelEnable, ExecuteAddPeerCommand);
            DeleteSelfCommand = new SimpleCommand(MindLevelEnable, ExecuteDeleteSelfCommand);
            MoveForwardCommand = new SimpleCommand(MindExecuteEnable, ExecuteMoveForwardCommand);
            MoveBackCommand = new SimpleCommand(MindExecuteEnable, ExecuteMoveBackCommand);

            MindNode level1node = new MindNode(this) { Left = 200, Top = 200, Text = "思维导图" };
            level1node.InitLayout(true);
            Items.Add(level1node);
            level1node.IsSelected = true;
        }

        public bool MindExecuteEnable(object para)
        {
            if (ExecuteEnable(para) == false) return false;

            if (SelectedItem is MindNode) return true;

            return false;
        }

        private bool MindLevelEnable(object obj)
        {
            if (MindExecuteEnable(obj) == false) return false;

            return (SelectedItem as MindNode).NodeLevel != 0;
        }

        #region 操作
        private void ExecutedChangeMindTypeCommand(object obj)
        {
            if (obj is MindType mindType)
            {
                Items.OfType<MindNode>().ToList().ForEach(item => { item.InitLayout(true); });
                Items.OfType<MindNode>().ToList().ForEach(item => { item.InitConnectLayout();  });
                RootItem?.LayoutUpdated();
            }
        }

        public void ExecuteAddChildCommand(object parameter)
        {
            List<MindNode> items = new List<MindNode>();
            if (parameter is MindNode parent)
            {

            }
            else if (parameter is IEnumerable<MindNode> para)
            {
                parent = para.FirstOrDefault();//第一个固定为父节点
                items = para.Skip(1).ToList();
            }
            else
            {
                parent = SelectedItem as MindNode;
            }

            if (items?.Count == 0)
            {
                var node = new MindNode(this) { Text = "分支主题" };
                items.Add(node);
            }

            DoCommandManager.DoNewCommand(this.ToString(),
                () => {
                    foreach (var item in items)
                    {
                        parent.AddChild(item);
                    }
                    parent.LayoutUpdated();
                },
                () => {
                    foreach (var item in items)
                    {
                        parent.RemoveChild(item);
                    }
                    parent.LayoutUpdated();
                });

        }

        public void ExecuteAddParentCommand(object parameter)
        {
            List<MindNode> items = new List<MindNode>();
            if (parameter is MindNode node)
            {

            }
            else if (parameter is IEnumerable<MindNode> para)
            {
                node = para.FirstOrDefault();//第一个固定为父节点
                items = para.Skip(1).ToList();
            }
            else
            {
                node = SelectedItem as MindNode;
            }
            if (items?.Count == 0)
            {
                items.Add(new MindNode(this) { Text = "分支主题" });
            }

            if (node.Parent is MindNode parent)
            {
                DoCommandManager.DoNewCommand(this.ToString(),
                     () => {
                         int index = parent.Children.IndexOf(node);

                         parent.AddChild(items[0], index + 1);
                         parent.RemoveChild(node);
                         items[0].AddChild(node);

                         parent.LayoutUpdated();
                     },
                     () => {
                         int index = parent.Children.IndexOf(items[0]);
                         items[0].RemoveChild(node);
                         parent.AddChild(node, index + 1);

                         parent.LayoutUpdated();
                     });


            }
        }

        public void ExecuteAddPeerCommand(object parameter)
        {
            List<MindNode> items = new List<MindNode>();
            if (parameter is MindNode pear)
            {

            }
            else if (parameter is IEnumerable<MindNode> para)
            {
                pear = para.FirstOrDefault();//第一个固定为同级节点
                items = para.Skip(1).ToList();
            }
            else
            {
                pear = SelectedItem as MindNode;
            }

            if (items?.Count == 0)
            {
                var node = new MindNode(this) { Text = "分支主题" };
                items.Add(node);
            }


            if (pear.Parent is MindNode parent)
            {
                DoCommandManager.DoNewCommand(this.ToString(),
                    () => {
                        int index = parent.Children.IndexOf(pear);
                        for (int i = 0; i < items.Count; i++)
                        {
                            parent.AddChild(items[i], index + i + 1);
                        }

                        parent.LayoutUpdated();
                    },
                    () => {
                        for (int i = 0; i < items.Count; i++)
                        {
                            parent.RemoveChild(items[i]);
                        }
                        parent.LayoutUpdated();
                    });

            }

        }

        private void ExecuteMoveBackCommand(object parameter)
        {
            if (parameter is MindNode node)
            {

            }
            else
            {
                node = SelectedItem as MindNode;
            }

            if (node.Parent is MindNode parent)
            {
                DoCommandManager.DoNewCommand(this.ToString(),
                    () => {
                        int index = parent.Children.IndexOf(node);
                        if (index < parent.Children.Count - 1)
                        {
                            parent.RemoveChild(node);
                            parent.AddChild(node, index + 1);
                            parent.LayoutUpdated();
                        }
                    },
                    () => {
                        int index = parent.Children.IndexOf(node);
                        if (index > 0)
                        {
                            parent.RemoveChild(node);
                            parent.AddChild(node, index - 1);
                            parent.LayoutUpdated();
                        }
                    });
            }

        }

        private void ExecuteMoveForwardCommand(object parameter)
        {
            if (parameter is MindNode node)
            {

            }
            else
            {
                node = SelectedItem as MindNode;
            }

            if (node.Parent is MindNode parent)
            {
                DoCommandManager.DoNewCommand(this.ToString(),
                  () => {
                      int index = parent.Children.IndexOf(node);
                      if (index > 0)
                      {
                          parent.RemoveChild(node);
                          parent.AddChild(node, index - 1);
                          parent.LayoutUpdated();
                      }
                  },
                  () => {
                      int index = parent.Children.IndexOf(node);
                      if (index < parent.Children.Count - 1)
                      {
                          parent.RemoveChild(node);
                          parent.AddChild(node, index + 1);
                          parent.LayoutUpdated();
                      }
                  });
            }

        }

        private void ExecuteDeleteSelfCommand(object parameter)
        {
            if (parameter is MindNode node)
            {

            }
            else
            {
                node = SelectedItem as MindNode;
            }

            if (node.Parent is MindNode parent)
            {
                int index = parent.Children.IndexOf(node);
                DoCommandManager.DoNewCommand(this.ToString(),
                  () => {
                      parent.RemoveChild(node, true);
                      parent.LayoutUpdated();
                  },
                  () => {
                      parent.AddChild(node, index);
                      parent.LayoutUpdated();
                  });
            }

        }
        #endregion

    }
}
